package me.zhengjie.service.impl;

import lombok.extern.slf4j.Slf4j;
import me.zhengjie.service.FlywayService;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.MigrationInfo;
import org.flywaydb.core.api.MigrationInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;

/**
 * Flyway 数据库迁移服务实现类
 * 
 * @author zhengjie
 * @date 2024-01-01
 */
@Slf4j
@Service
public class FlywayServiceImpl implements FlywayService {

    @Autowired
    private DataSource dataSource;

    private Flyway flyway;

    /**
     * 获取 Flyway 实例
     */
    private Flyway getFlyway() {
        if (flyway == null) {
            flyway = Flyway.configure()
                    .dataSource(dataSource)
                    .encoding("UTF-8")
                    .locations("classpath:db/migration")
                    .sqlMigrationPrefix("V")
                    .sqlMigrationSeparator("__")
                    .sqlMigrationSuffixes(".sql")
                    .validateOnMigrate(true)
                    .baselineOnMigrate(true)
                    .baselineVersion("1")
                    .mixed(false)
                    .load();
        }
        return flyway;
    }

    @Override
    public void migrate() {
        try {
            log.info("开始执行数据库迁移...");
            getFlyway().migrate();
            log.info("数据库迁移完成");
        } catch (Exception e) {
            log.error("数据库迁移失败", e);
            throw new RuntimeException("数据库迁移失败", e);
        }
    }

    @Override
    public String getMigrationInfo() {
        try {
            MigrationInfoService migrationInfoService = getFlyway().info();
            MigrationInfo[] migrationInfos = migrationInfoService.all();
            
            StringBuilder info = new StringBuilder();
            info.append("数据库迁移信息:\n");
            
            for (MigrationInfo migrationInfo : migrationInfos) {
                info.append("版本: ").append(migrationInfo.getVersion())
                    .append(", 描述: ").append(migrationInfo.getDescription())
                    .append(", 状态: ").append(migrationInfo.getState())
                    .append(", 执行时间: ").append(migrationInfo.getInstalledOn())
                    .append("\n");
            }
            
            return info.toString();
        } catch (Exception e) {
            log.error("获取迁移信息失败", e);
            return "获取迁移信息失败: " + e.getMessage();
        }
    }

    @Override
    public void clean() {
        try {
            log.warn("开始清理数据库...");
            getFlyway().clean();
            log.info("数据库清理完成");
        } catch (Exception e) {
            log.error("数据库清理失败", e);
            throw new RuntimeException("数据库清理失败", e);
        }
    }

    @Override
    public void validate() {
        try {
            log.info("开始验证迁移脚本...");
            getFlyway().validate();
            log.info("迁移脚本验证通过");
        } catch (Exception e) {
            log.error("迁移脚本验证失败", e);
            throw new RuntimeException("迁移脚本验证失败", e);
        }
    }
} 